package com.sam.spring.chapter2.helloworld;

import junit.framework.Assert;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.sam.spring.chapter1.helloworld.HelloAPI;
import com.sam.spring.chapter2.bean.BooleanTestBean;
import com.sam.spring.chapter2.bean.CollectionTestBean;
import com.sam.spring.chapter2.bean.ListTestBean;
import com.sam.spring.chapter2.bean.NavigationA;
import com.sam.spring.chapter2.bean.NavigationC;

public class HelloTest {
	@Test
	public void testConstructorDependencyInjectTest() {
		BeanFactory beanFactory = new ClassPathXmlApplicationContext(
				"chapter2/helloSpring.xml");
		// 获取根据参数索引依赖注入的Bean
		HelloAPI byIndex = beanFactory.getBean("byIndex", HelloAPI.class);
		byIndex.sayHello();
		// 获取根据参数类型依赖注入的Bean
		HelloAPI byType = beanFactory.getBean("byType", HelloAPI.class);
		byType.sayHello();
		// 获取根据参数名字依赖注入的Bean
		HelloAPI byName = beanFactory.getBean("byName", HelloAPI.class);
		byName.sayHello();
	}

	@Test
	public void testSetterDependencyInject() {
		BeanFactory beanFactory = new ClassPathXmlApplicationContext(
				"chapter2/helloSpring.xml");
		HelloAPI bean = beanFactory.getBean("bean", HelloAPI.class);
		bean.sayHello();
	}

	@Test
	public void testBooleanBean() {
		BeanFactory beanFactory = new ClassPathXmlApplicationContext(
				"chapter2/helloSpring.xml");
		BooleanTestBean booleanTestBean = beanFactory.getBean("bean2",
				BooleanTestBean.class);
		System.out.println(booleanTestBean.isSuccess());

		booleanTestBean = beanFactory.getBean("bean3", BooleanTestBean.class);
		System.out.println(booleanTestBean.isSuccess());

		booleanTestBean = beanFactory.getBean("bean4", BooleanTestBean.class);
		System.out.println(booleanTestBean.isSuccess());
	}

	@Test
	public void testListInject() {
		BeanFactory beanFactory = new ClassPathXmlApplicationContext(
				"chapter2/helloSpring.xml");
		ListTestBean listBean = beanFactory.getBean("listBean",
				ListTestBean.class);
		System.out.println(listBean.getValues().size());
		Assert.assertEquals(3, listBean.getValues().size());
	}

	@Test
	public void testSetInject() {
		BeanFactory beanFactory = new ClassPathXmlApplicationContext(
				"chapter2/helloSpring.xml");
		CollectionTestBean listBean = beanFactory.getBean("setBean",
				CollectionTestBean.class);
		System.out.println(listBean.getValues().size());
		Assert.assertEquals(3, listBean.getValues().size());
	}

	@Test
	public void testBeanInject() {
		BeanFactory beanFactory = new ClassPathXmlApplicationContext(
				"chapter2/helloSpring1.xml");
		// 通过构造器方式注入
		HelloAPI bean1 = beanFactory.getBean("bean1", HelloAPI.class);
		bean1.sayHello();
		// 通过setter方式注入
		HelloAPI bean2 = beanFactory.getBean("bean2", HelloAPI.class);
		bean2.sayHello();
	}
	
	@Test
	public void testLocalAndParentBeanInject() {
		ApplicationContext parentBeanContext = new ClassPathXmlApplicationContext(
				"chapter2/parentBeanInject.xml");
		ApplicationContext localBeanContext = new ClassPathXmlApplicationContext(
				new String[] { "chapter2/localBeanInject.xml" },
				parentBeanContext);
		HelloAPI bean1 = localBeanContext.getBean("bean1", HelloAPI.class);
		bean1.sayHello();// 该Bean引用Local bean

		HelloAPI bean2 = localBeanContext.getBean("bean2", HelloAPI.class);
		bean2.sayHello();// 该Bean引用parent bean
	}
	
	@Test
	public void testInnerBeanInject() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"chapter2/innerBeanInject.xml");
		HelloAPI bean = context.getBean("bean", HelloAPI.class);
		bean.sayHello();
	}
	
	// 对象图导航
	@Test
	public void testNavigationBeanInject() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"chapter2/navigationBeanInject.xml");
		NavigationA navigationA = context.getBean("a", NavigationA.class);
		navigationA.getNavigationB().getNavigationC().sayNavigation();
		navigationA.getNavigationB().getList().get(0).sayNavigation();
		navigationA.getNavigationB().getMap().get("key").sayNavigation();
		navigationA.getNavigationB().getArray()[0].sayNavigation();
		((NavigationC) navigationA.getNavigationB().getProperties().get("1"))
				.sayNavigation();
	}
}
